package gang.org.springframework.framework.core.type.classreading;

import gang.org.springframework.framework.asm.GangSimpleAnnotationMetadataReadingVisitor;
import gang.org.springframework.framework.io.GangResource;
import gang.org.springframework.framework.metadata.GangAnnotationMetadata;
import gang.org.springframework.framework.metadata.GangClassMetadata;
import jdk.internal.org.objectweb.asm.ClassReader;

import java.io.IOException;
import java.io.InputStream;

public class GangSimpleMetadataReader implements GangMetadataReader{

    private static final int PARSING_OPTIONS = ClassReader.SKIP_DEBUG
            | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES;

    private final GangResource resource;

    private final GangAnnotationMetadata annotationMetadata;

    public GangSimpleMetadataReader(GangResource resource, ClassLoader classLoader) {
        //###########################################################
        GangSimpleAnnotationMetadataReadingVisitor visitor = new GangSimpleAnnotationMetadataReadingVisitor(classLoader);
        ClassReader classReader = getClassReader(resource);

        /**
         * *Visitor类中方法，在accept方法中被执行
         * */
        classReader.accept(visitor,PARSING_OPTIONS);
        //###########################################################
        this.resource = resource;

        this.annotationMetadata = visitor.getMetadata();
    }

    @Override
    public GangAnnotationMetadata getAnnotationMetadata() {
        return annotationMetadata;
    }

    private static ClassReader getClassReader(GangResource resource){
        ClassReader classReader = null;
        try {
            final InputStream inputStream = resource.getInputStream();
            classReader = new ClassReader(inputStream);
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return classReader;
    }

    @Override
    public GangResource getResource() {
        return resource;
    }

    @Override
    public GangClassMetadata getClassMetadata() {
        return this.annotationMetadata;
    }
}
